﻿using System.Security.Cryptography;
using System.Text;

namespace HEFramework
{
    /// <summary>
    ///
    /// 哈希值计算
    /// 
    /// ----------------------------------------
    /// 作者 hep
    /// 创建时间：2023-12-22 17:48:30
    /// ----------------------------------------
    /// </summary>
    public class Hash<T> where T : HashAlgorithm, new()
    {
        /// <summary>
        /// 获取哈希字符串（字节数组）
        /// </summary>
        /// <param name="_bytes">字节</param>
        /// <returns></returns>
        public static string ComputeHashToHex(byte[] _bytes)
        {
            byte[] hashBytes = ComputeHash(_bytes);
            return GetHex(hashBytes);
        }

        /// <summary>
        /// 获取哈希字符串（文本）
        /// </summary>
        /// <param name="_text">文本</param>
        /// <returns></returns>
        public static string ComputeHashToHex(string _text)
        {
            byte[] hashBytes = ComputeHash(_text);
            return GetHex(hashBytes);
        }

        /// <summary>
        /// 获取哈希字符串（内存流）
        /// </summary>
        /// <param name="_stream">内存流</param>
        /// <returns></returns>
        public static string ComputeHashToHex(System.IO.Stream _stream)
        {
            byte[] hashBytes = ComputeHash(_stream);
            return GetHex(hashBytes);
        }


        /// <summary>
        /// 获取哈希值
        /// </summary>
        /// <param name="_hashBytes">输入字节</param>
        /// <returns></returns>
        private static string GetHex(byte[] _hashBytes)
        {
            StringBuilder builder = new StringBuilder(64);
            for (int i = 0; i < _hashBytes.Length; ++i)
            {
                builder.Append(_hashBytes[i].ToString("x2"));
            }

            return builder.ToString();
        }


        /// <summary>
        /// 计算哈希值(字节)
        /// </summary>
        /// <param name="_bytes">データ</param>
        public static byte[] ComputeHash(byte[] _bytes)
        {
            using (var provider = new T())
            {
                return provider.ComputeHash(_bytes);
            }
        }

        /// <summary>
        /// 计算哈希值(文本)
        /// </summary>
        /// <param name="_text">データ</param>
        private static byte[] ComputeHash(string _text)
        {
            using (var provider = new T())
            {
                return provider.ComputeHash(Encoding.UTF8.GetBytes(_text));
            }
        }

        /// <summary>
        /// 计算哈希值(内存流)
        /// </summary>
        /// <param name="_stream">データ</param>
        private static byte[] ComputeHash(System.IO.Stream _stream)
        {
            using (var provider = new T())
            {
                return provider.ComputeHash(_stream);
            }
        }
    }


    /// <summary>
    /// MD5
    /// </summary>
    public class MD5Hash : Hash<MD5CryptoServiceProvider>
    {
    }

    /// <summary>
    /// SHA256
    /// </summary>
    public class SHA256Hash : Hash<SHA256CryptoServiceProvider>
    {
    }
}